﻿
Imports remotecall

Public Class rcDetector
    Public Class remotecallName
        Public Const runjob As String = "runjob"
    End Class
End Class

Public MustInherit Class rcDetector(Of SERVER_T, INPUT_T, OUTPUT_T)
    Inherits detector

    Private server As SERVER_T = Nothing

    Protected MustOverride Function create_server(ByVal port As Int32, ByVal connectionCount As Int64) As SERVER_T
    Protected MustOverride Function start_server(ByVal server As SERVER_T,
                                                 ByVal port As Int32,
                                                 ByVal connectionCount As Int64) As Boolean
    Protected MustOverride Sub register(ByVal server As SERVER_T,
                                        ByVal name As String,
                                        ByVal d As _do(Of INPUT_T, pointer(Of OUTPUT_T), eventComb))
    Protected MustOverride Sub stop_server(ByVal server As SERVER_T)
    Protected MustOverride Function parse_input_valid(ByVal i As INPUT_T) As Boolean
    Protected MustOverride Function parse_input_ijob(ByVal i As INPUT_T, ByRef o As ijob) As Boolean
    Protected MustOverride Function create_output() As OUTPUT_T
    Protected MustOverride Sub inject_output_ijob(ByVal i As OUTPUT_T, ByVal job As ijob)

    Private Function runjob(ByRef arg As INPUT_T, ByRef prtn As pointer(Of OUTPUT_T)) As eventComb
        Dim ijob As ijob = Nothing
        If parse_input_valid(arg) AndAlso
           parse_input_ijob(arg, ijob) Then
            assert(Not ijob Is Nothing)
            Dim rtn As pointer(Of OUTPUT_T) = Nothing
            rtn = prtn
            Dim ec As eventComb = Nothing
            ec = New eventComb(Function() As Boolean
                                   Return waitfor(invoke(ijob)) AndAlso goto_next()
                               End Function,
                               Function() As Boolean
                                   Dim r As OUTPUT_T = Nothing
                                   r = create_output()
                                   assert(Not r Is Nothing)
                                   inject_output_ijob(r, ijob)
                                   Return eva(rtn, r) AndAlso goto_end()
                               End Function)
            Return ec
        Else
            raiseError(errorHandle.errorType.warning, "not a valid ijob inputed")
            Return eventComb.failed()
        End If
    End Function

    Protected NotOverridable Overrides Sub startImpl(ByVal port As Int32, ByVal connectionCount As Int64)
        server = create_server(port, connectionCount)
        assert(Not server Is Nothing)
        register(server, rcDetector.remotecallName.runjob, AddressOf runjob)
        If start_server(server, port, connectionCount) Then
            raiseError("rcDetector started on port ", port)
        Else
            raiseError(errorHandle.errorType.system, "cannot start rcserve4 on port ", port, ", ignore rcDetector.")
        End If
    End Sub

    Public NotOverridable Overrides Sub [stop]()
        stop_server(server)
    End Sub
End Class
